<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryFormRef" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="电站名称" prop="stationName">
        <el-input v-model="queryParams.stationName" placeholder="请输入电站名称" clearable @keyup.enter="handleQuery" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['station:add']">新增
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
          v-hasPermi="['station:edit']">修改
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['station:remove']">删除
        </el-button>
      </el-col>
      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="infoList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="电站名称" align="center" prop="stationName" />
      <el-table-column label="详细地址" align="center" prop="address" />
      <el-table-column label="消费套餐" align="center">
        <template #default="scope">
          <el-button type="primary" @click="gotoCharge(scope.row)">
            设置
          </el-button>
        </template>
      </el-table-column>
      <el-table-column label="运营商设置" align="center" class-name="flex_group">
        <template #default="scope">
          <el-button :type="scope.row.companyId == -1 || scope.row.companyId == null ? 'primary' : 'warning'"
            @click="handleBind(scope.row)">
            <span>
              {{ scope.row.companyId == -1 || scope.row.companyId == null ? "绑定主体" : "更新主体" }}
            </span>
          </el-button>
        </template>
      </el-table-column>
      <el-table-column label="电站电桩" align="center" class-name="flex_group">
        <template #default="scope">
          <el-button type="primary" v-hasPermi="['station:bind']" @click="handleBindDev(scope.row)">
            <span>绑定电桩</span>
          </el-button>
          <el-button type="warning" v-hasPermi="['station:unbind']" @click="handleUnbindDev(scope.row)">
            <span>电桩解绑</span>
          </el-button>
        </template>
      </el-table-column>
      <!-- <el-table-column label="创建信息" align="center">
     <template #default="scope">
      <span class="modify">{{ scope.row.createBy || "-" }}</span>
      <span class="modify">{{
        parseTime(scope.row.createTime, "{y}-{m}-{d}")
      }}</span>
    </template>
  </el-table-column> -->
      <!-- <el-table-column label="更新信息" align="center">
     <template #default="scope">
      <span class="modify">{{ scope.row.updateBy || "-" }}</span>
      <span class="modify">{{
        parseTime(scope.row.updateTime, "{y}-{m}-{d}")
      }}</span>
    </template>
  </el-table-column> -->
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template #default="scope">
          <el-button link icon="Document" @click="handleInfo(scope.row)" v-hasPermi="['station:query']">详情
          </el-button>
          <el-button link icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['station:edit']">修改
          </el-button>
          <el-button link icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['station:remove']">删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
      @pagination="getList" />

    <!-- 添加或修改电站对话框 -->
    <el-dialog :title="title" v-model="open" width="900px" append-to-body :close-on-click-modal="false">
      <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="电站名称" prop="stationName">
          <el-input v-model="form.stationName" placeholder="请输入电站名称" />
        </el-form-item>
        <el-form-item label="省/市/区">
          <el-cascader filterable ref="refPCA" :options="pcaList" :props="defaultProps" @change="handlePCA"
            v-model="selectArea" popper-class="area" placeholder="省/市/区">
            <template #default="{ node, data }">
              <span>{{ data.name }}</span>
            </template>
          </el-cascader>
        </el-form-item>
        <el-form-item label="详细地址" prop="address">
          <el-input v-model="form.address" placeholder="请输入详细地址">
            <template #suffix>
              <el-button type="primary" @click="mapLocation">地图定位</el-button>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item v-if="isMap">
          <div id="bmap"></div>
        </el-form-item>
        <el-form-item label="附近地址" v-if="surroundingPois.length > 0">
          <el-row class="near_row" :gutter="10">
            <el-col class="mb10" :span="12" v-for="(item, key) in surroundingPois" :key="key">
              <el-card shadow="never">
                <template #header>
                  <div class="flex_cont">
                    <span>{{ item.title }}</span>
                    <el-button class="ml10" type="primary" @click="checkAddr(item)">选择</el-button>
                  </div>
                </template>
                <el-tooltip effect="dark" :content="item.address" placement="top">
                  <span class="addr">{{ item.address }}</span>
                </el-tooltip>
              </el-card>
            </el-col>
          </el-row>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
    <DialogBind ref="dialogBind" :reload="getList" />
    <DialogBindDev ref="dialogBindDev" :reload="getList" />
    <DialogUnbindDev ref="dialogUnbindDev" :reload="getList" />
  </div>
</template>

<script setup name="Station">
import { addStation, delStation, getStation, listPCA, listStation, updateStation } from "@/api/equipment/station";
import { loadBMap } from "@/utils/map.js";
import { ElNotification } from "element-plus";
import DialogBind from "@/dialog/station/DialogBind";
import DialogBindDev from "@/dialog/station/DialogBindDev";
import DialogUnbindDev from "@/dialog/station/DialogUnbindDev";

const route = useRoute();
const router = useRouter();
const { proxy } = getCurrentInstance();
const { dev_status, dev_version } = proxy.useDict("dev_status", "dev_version");

const loading = ref(true)
const ids = ref([])
const stationNames = ref([])
const single = ref(true)
const multiple = ref(true)
const showSearch = ref(true)
const total = ref(0)
const infoList = ref([])
const pcaList = ref([])
const title = ref("")
const open = ref(false)
const selectArea = ref([])
const isMap = ref(null)
const lnglat = ref(null)
const surroundingPois = ref(null)
const mouseLoc = ref({
  province: null,
  city: null,
  area: null,
})
const data = reactive({
  // 查询参数
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    stationName: null,
  },
  queryComp: {},
  // 层级省/市/区选择
  defaultProps: {
    children: "childVo",
    label: "name",
    value: "id",
    checkStrictly: true,
  },
  // 表单参数
  form: {
    stationId: null,
    stationName: null,
    longitude: null,
    latitude: null,
    address: null,
    provinceId: null,
    cityId: null,
    districtId: null,
    remark: null,
  },
  // 表单校验
  rules: {
    stationName: [
      { required: true, message: "电站名称不能为空", trigger: "blur" }
    ],
    longitude: [
      { required: true, message: "经度不能为空", trigger: "blur" }
    ],
    latitude: [
      { required: true, message: "纬度不能为空", trigger: "blur" }
    ],
    address: [
      { required: true, message: "详细地址不能为空", trigger: "blur" }
    ],
    provinceId: [{ required: true, message: "请选择省", trigger: "blur" }],
    cityId: [{ required: true, message: "请选择市", trigger: "blur" }],
    districtId: [{ required: true, message: "请选择区", trigger: "blur" }],
  }
});

const { queryParams, queryComp, defaultProps, form, rules } = toRefs(data);

// 查询电站列表
function getList() {
  loading.value = true;
  if (queryParams.value.stationName == "") queryParams.value.stationName = null;
  listStation(queryParams.value).then((response) => {
    infoList.value = response.rows;
    total.value = response.total;
    loading.value = false;
  });
}

// 查询省市区
function getPCA() {
  listPCA().then((response) => {
    if (response.data) {
      pcaList.value = dataFormat(response.data);
    }
  });
}

// 绑定省
function handlePCA(val) {
  if (val != null) {
    let data_1 = pcaList.value.find((item) => item.id == selectArea.value[0]);
    form.value.provinceId = data_1.id;
    if (selectArea.value.length == 1) {
      if (data_1.childVo.length != 0) {
        return;
      }
    } else {
      handleCity(data_1, 1);
    }
  } else {
    return;
  }
}

// 绑定市
function handleCity(dataitem, val) {
  let data = dataitem.childVo.find(
    (item) => item.id == selectArea.value[val]
  );
  form.value.cityId = data.id;
  if (selectArea.value.length == val + 1) {
    if (data.childVo.length != 0) {
      return;
    }
  } else {
    handleArea(data, val + 1);
  }
}

// 绑定区
function handleArea(dataitem, val) {
  let data = dataitem.childVo.find(
    (item) => item.id == selectArea.value[val]
  );
  if (selectArea.value.length == val + 1) {
    form.value.districtId = data.id;
  }
}

// 省市区数据格式化
function dataFormat(data) {
  for (var i = 0; i < data.length; i++) {
    if (data[i].childVo != null) {
      if (data[i].childVo.length < 1 || data[i].type > 2) {
        // childVo若为空数组，则将childVo设为undefined
        data[i].childVo = undefined;
      } else {
        // childVo若不为空数组，则继续 递归调用 本方法
        dataFormat(data[i].childVo);
      }
    } else {
      data[i].childVo = undefined;
    }
  }
  return data;
}

// 自动绑定省
function autoBind() {
  let data_1 = pcaList.value.find(
    (item) => item.name == mouseLoc.value.province
  );
  if (data_1 != null) {
    form.value.provinceId = data_1.id;
    autoBindCity(pcaList);
  }
}

// 自动绑定市
function autoBindCity(dataitem) {
  for (let index = 0; index < dataitem.length; index++) {
    let list = dataitem[index].childVo;
    let data = list.find((item) => item.name == mouseLoc.value.city);
    if (data != null) {
      form.value.cityId = data.id;
      autoBindArea(list);
    }
  }
}

// 自动绑定区
function autoBindArea(dataitem) {
  for (let index = 0; index < dataitem.length; index++) {
    let list = dataitem[index].childVo;
    let data = list.find((item) => item.name == mouseLoc.value.area);
    if (data != null) {
      form.value.districtId = data.id;
      selectArea.value = data.id;
    }
  }
}

// 识别绑定省
function bind() {
  let data_1 = pcaList.value.find((item) => item.id == form.value.provinceId);
  if (data_1 != null) {
    form.value.provinceId = data_1.id;
    bindCity(pcaList.value);
  }
}

// 识别绑定市
function bindCity(dataitem) {
  for (let index = 0; index < dataitem.length; index++) {
    let list = dataitem[index].childVo;
    let data = list.find((item) => item.id == form.value.cityId);
    if (data != null) {
      form.value.cityId = data.id;
      bindArea(list);
    }
  }
}

// 识别绑定区
function bindArea(dataitem) {
  for (let index = 0; index < dataitem.length; index++) {
    let list = dataitem[index].childVo;
    let data = list.find((item) => item.id == form.value.districtId);
    if (data != null) {
      form.value.districtId = data.id;
      selectArea.value = data.id;
    }
  }
}

// 点击触发地图定位
function mapLocation() {
  isMap.value = true;
  if (form.value.address) {
    changelnglat(form.value.address);
  } else {
    getLocation();
  }
}

// 确认地址并更新地图
function checkAddr(item) {
  form.value.address = item.address;
  form.value.latitude = item.point.lat;
  form.value.longitude = item.point.lng;
  createMap(item.point);
}

// 渲染地图
function createMap(lnglat) {
  var map = new BMap.Map("bmap"); // 创建地图实例,这里用到了id选择器
  if (lnglat != null) {
    map.centerAndZoom(lnglat, 18); // 创建城市坐标
    var marker = new BMap.Marker(new BMap.Point(lnglat.lng, lnglat.lat));
    map.addOverlay(marker);
  } else {
    map.centerAndZoom("瑞安市", 18); // 创建城市坐标
  }
  // 地图缩放控件
  map.addControl(new BMap.NavigationControl());
  map.addControl(
    new BMap.ScaleControl({
      anchor: BMAP_ANCHOR_BOTTOM_LEFT,
    })
  );
  map.addControl(
    new BMap.CityListControl({
      anchor: BMAP_ANCHOR_TOP_RIGHT,
    })
  );
  map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
  // 地址解析
  var geoc = new BMap.Geocoder();
  // 监听点击事件获得当前地址
  map.addEventListener("click", function (e) {
    map.clearOverlays();
    map.panTo(e.point);
    form.value.longitude = e.point.lng;
    form.value.latitude = e.point.lat;
    geoc.getLocation(e.point, function (position) {
      lnglat.value = position.point;
      form.value.address = position.address;
      mouseLoc.value = {
        province: position.addressComponents.province,
        city: position.addressComponents.city,
        area: position.addressComponents.district,
      };
      autoBind();
      console.log("点击地图的当前地址", position);
      surroundingPois.value = position.surroundingPois;
    });
    var marker = new BMap.Marker(new BMap.Point(e.point.lng, e.point.lat));
    map.addOverlay(marker);
  });
}

// 错略定位--百度地图
function getLocation() {
  var map = new BMap.Map("bmap");
  var geolocation = new BMap.Geolocation();
  geolocation.getCurrentPosition(function (res) {
    let that = this
    if (that.getStatus() == BMAP_STATUS_SUCCESS) {
      console.log("百度精准定位：", res);
      let formattedAddress =
        res.address.province +
        res.address.city +
        res.address.district +
        res.address.street +
        res.address.street_number;
      changelnglat(formattedAddress);
    } else {
      console.log("百度定位失败：", that.getStatus());
      getH5location();
    }
  });
}

// H5定位-- 浏览器定位
function getH5location() {
  window.navigator.geolocation.getCurrentPosition(
    function (position) {
      // 经度 position.coords.longitude
      // 纬度 position.coords.latitude
      // 准确度 position.coords.accuracy;
      // 海拔 position.coords.altitude;
      // 海拔准确度 position.coords.altitudeAcuracy
      // 行进方向 position.coords.heading
      // 地面速度 position.coords.speed
      // 请求的时间 new Date(position.timestamp)
      console.log("浏览器H5定位：", position.coords);
      let res = position.coords;
      changelocation(res.longitude, res.latitude);
    },
    function (err) {
      console.log("浏览器H5定位失败：", err.message);
      switch (err.code) {
        case 0:
          ElNotification({
            message: "获取当前位置失败",
            type: "error",
          });
          break;
        case 1:
          ElNotification({
            message: "用户拒绝浏览器获取位置信息",
            type: "error",
          });
          break;
        case 2:
          ElNotification({
            message: "尝试获取用户信息，但失败了",
            type: "error",
          });
          break;
        case 3:
          ElNotification({
            message: "获取位置超时了",
            type: "error",
          });
          break;
      }
      // code：返回获取位置的状态
      //          0  :  不包括其他错误编号中的错误
      // ​		     1  :  用户拒绝浏览器获取位置信息
      // ​		     2  :  尝试获取用户信息，但失败了
      // ​		     3  :  设置了timeout值，获取位置超时了
    },
    {
      enableHighAcuracy: true, //位置是否精确获取
      timeout: 5000, //获取位置允许的最长时间
      maximumAge: 1000, //多久更新获取一次位置
    }
  );
}

// 正向地址解析(地址→坐标)
function changelnglat(address) {
  var map = new BMap.Map("bmap");
  var myGeo = new BMap.Geocoder();
  // 将地址解析结果显示在地图上，并调整地图视野
  myGeo.getPoint(address, function (point) {
    if (point) {
      console.log("定位地址转换坐标：", point);
      changelocation(point.lng, point.lat);
    } else {
      ElNotification({
        message: "您选择的地址没有解析到结果！",
        type: "error",
      });
      return;
    }
  });
}

// 逆向地址解析(坐标→地址)
function changelocation(lng, lat) {
  var map = new BMap.Map("bmap");
  var myGeo = new BMap.Geocoder();
  // 将地址解析结果显示在地图上，并调整地图视野
  let lnglat = new BMap.Point(lng, lat);
  myGeo.getLocation(lnglat, function (position) {
    if (position) {
      console.log("定位坐标转换地址：", position);
      surroundingPois.value = position.surroundingPois;
      form.value.address = position.address;
      lnglat.value = position.point;
      form.value.longitude = position.point.lng;
      form.value.latitude = position.point.lat;
      mouseLoc.value = {
        province: position.addressComponents.province,
        city: position.addressComponents.city,
        area: position.addressComponents.district,
      };
      autoBind();
      createMap(lnglat.value);
    } else {
      ElNotification({
        message: "您选择的地址没有解析到结果！",
        type: "error",
      });
      return;
    }
  });
}

// 取消新增/修改按钮
function cancel() {
  open.value = false;
  reset();
}

// 新增/修改表单重置
function reset() {
  form.value = {
    stationId: null,
    stationName: null,
    longitude: null,
    latitude: null,
    address: null,
    provinceId: null,
    cityId: null,
    districtId: null,
    remark: null,
  };
  selectArea.value = [];
  surroundingPois.value = [];
  proxy.resetForm("formRef");
}

// 搜索按钮操作
function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
}

// 重置搜索框按钮操作
function resetQuery() {
  proxy.resetForm("queryFormRef");
  handleQuery();
}

// 多选框选中数据
function handleSelectionChange(selection) {
  ids.value = selection.map((item) => item.stationId);
  stationNames.value = selection.map((item) => item.stationName);
  single.value = selection.length !== 1;
  multiple.value = !selection.length;
}

// 新增电站按钮操作
function handleAdd() {
  reset();
  open.value = true;
  title.value = "添加电站";
}

// 修改电站按钮操作
function handleUpdate(row) {
  reset();
  const id = row.stationId || ids.value;
  getStation(id).then((response) => {
    form.value = response.data;
    bind();
    open.value = true;
    title.value = "修改电站";
  });
}

// 绑定设备按钮操作
function handleBind(row) {
  proxy.$refs["dialogBind"].open(row);
}

function handleBindDev(row) {
  proxy.$refs["dialogBindDev"].open(row);
}

function handleUnbindDev(row) {
  proxy.$refs["dialogUnbindDev"].open(row);
}

// 电站详情按钮操作
function handleInfo(row) {
  router.push({
    path: "/equipment/station/info",
    query: { stationId: row.stationId }
  });
}

// 充电套餐设置按钮操作
function gotoCharge(row) {
  router.push({
    path: "/equipment/station/charge",
    query: { stationId: row.stationId }
  });
}

// 提交新增/修改按钮
function submitForm() {
  proxy.$refs["formRef"].validate((valid) => {
    if (valid) {
      // if (form.value.longitude == null || form.latitude == null) {
      //   proxy.$modal.msgWarning("未设置地图定位");
      //   return
      // }
      if (form.value.stationId != null) {
        updateStation(form.value).then((response) => {
          proxy.$modal.msgSuccess("修改成功");
          open.value = false;
          getList();
        });
      } else {
        addStation(form.value).then((response) => {
          proxy.$modal.msgSuccess("新增成功");
          open.value = false;
          getList();
        });
      }
    }
  });
}

// 删除电站按钮操作
function handleDelete(row) {
  const sids = [row.stationId] || ids.value;
  const names = row.stationName || stationNames.value;
  proxy.$modal
    .confirm('是否确认删除电站："' + names + '"？')
    .then(function () {
      return delStation(sids);
    })
    .then(() => {
      getList();
      proxy.$modal.msgSuccess("删除成功");
    })
    .catch(() => {
    });
}

getList();
getPCA();
loadBMap().then((res) => { });
</script>

<style lang="scss" scoped>
.near_row{
  width: 100%;
}
</style>
